import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { chatApi, personaApi } from "@/api/services";
import { useUserStore } from "./user";
import { useWebSocket } from "@/composables/useWebSocket";
import type {
  ChatSession,
  ChatMessage,
  MessageType,
  SessionStatus,
  Persona,
  Attachment,
} from "@/types/chat";

export const useChatStore = defineStore("chat", () => {
  // 状态
  const sessions = ref<ChatSession[]>([]);
  const currentSessionId = ref<string | null>(null);
  const messages = ref<Record<string, ChatMessage[]>>({});
  const isLoading = ref(false);
  const isStreaming = ref(false);
  const streamingMessageId = ref<string | null>(null);
  const currentPersona = ref<Persona | null>(null);
  const personas = ref<Persona[]>([]);
  const attachments = ref<Attachment[]>([]);
  const unreadCounts = ref<Record<string, number>>({});
  const searchQuery = ref("");
  const streamingMessage = ref<ChatMessage | null>(null);
  const isConnected = ref(false);

  // WebSocket 连接
  let websocket: WebSocket | null = null;
  let reconnectTimer: NodeJS.Timeout | null = null;
  let heartbeatTimer: NodeJS.Timeout | null = null;

  // 计算属性
  const currentSession = computed(() => {
    if (!currentSessionId.value) return null;
    return sessions.value.find((s) => s.id === currentSessionId.value) || null;
  });

  const currentMessages = computed(() => {
    if (!currentSessionId.value) return [];
    return messages.value[currentSessionId.value] || [];
  });

  const activeSessions = computed(() => {
    return sessions.value.filter((s) => s.status === "active");
  });

  const archivedSessions = computed(() => {
    return sessions.value.filter((s) => s.status === "archived");
  });

  const totalUnreadCount = computed(() => {
    return Object.values(unreadCounts.value).reduce(
      (sum, count) => sum + count,
      0,
    );
  });

  const hasAttachments = computed(() => {
    return attachments.value.length > 0;
  });

  const canSendMessage = computed(() => {
    return (
      !isLoading.value &&
      !isStreaming.value &&
      currentSession.value?.status === "active"
    );
  });

  const filteredSessions = computed(() => {
    if (!searchQuery.value) return sessions.value;
    const query = searchQuery.value.toLowerCase();
    return sessions.value.filter(
      (session) =>
        session.title.toLowerCase().includes(query) ||
        session.persona?.name.toLowerCase().includes(query),
    );
  });

  const availablePersonas = computed(() => {
    return personas.value.filter((p) => p.isActive);
  });

  const currentPersonaName = computed(() => {
    return currentPersona.value?.name || "默认助手";
  });

  // 动作
  const initChat = async () => {
    try {
      setLoading(true);

      // 获取人格列表
      await fetchPersonas();

      // 获取会话列表
      await fetchSessions();

      // 建立WebSocket连接
      await connectWebSocket();
    } catch (error) {
      throw error;
    } finally {
      setLoading(false);
    }
  };

  const fetchPersonas = async () => {
    try {
      const personaList = await personaApi.getPersonas();
      personas.value = personaList;

      // 设置默认人格
      if (!currentPersona.value && personaList.length > 0) {
        currentPersona.value =
          personaList.find((p) => p.isDefault) || personaList[0];
      }
    } catch (error) {
      throw error;
    }
  };

  const fetchSessions = async () => {
    try {
      isLoading.value = true;
      const sessionList = await chatApi.getSessions();
      sessions.value = sessionList;

      // 加载未读计数
      await loadUnreadCounts();

      // 如果没有当前会话，选择最近的会话
      if (!currentSession.value && sessionList.length > 0) {
        await selectSession(sessionList[0].id);
      }
    } catch (error) {
      throw error;
    } finally {
      isLoading.value = false;
    }
  };

  const loadUnreadCounts = async () => {
    try {
      for (const session of sessions.value) {
        const count = await chatApi.getUnreadCount(session.id);
        unreadCounts.value[session.id] = count;
      }
    } catch (error) {
      // 忽略未读计数加载错误
    }
  };

  const createSession = async (sessionData: {
    title?: string;
    personaId?: string;
    type?: "chat" | "group";
  }) => {
    try {
      isLoading.value = true;
      const response = await chatApi.createSession(sessionData);
      const newSession = response.data;

      sessions.value.unshift(newSession);
      messages.value[newSession.id] = [];
      unreadCounts.value[newSession.id] = 0;

      // 自动切换到新会话
      await selectSession(newSession.id);

      return response;
    } catch (error) {
      throw error;
    } finally {
      isLoading.value = false;
    }
  };

  const selectSession = async (sessionId: string) => {
    try {
      const session = sessions.value.find((s) => s.id === sessionId);
      if (!session) {
        throw new Error("会话不存在");
      }

      currentSessionId.value = sessionId;

      // 加载会话消息
      if (!messages.value[sessionId]) {
        await loadMessages(sessionId);
      }

      // 标记为已读
      await markAsRead(sessionId);

      // 设置当前人格
      if (session.persona) {
        currentPersona.value = session.persona;
      }

      return session;
    } catch (error) {
      throw error;
    }
  };

  const loadMessages = async (sessionId: string, page = 1, limit = 50) => {
    try {
      const response = await chatApi.getMessages(sessionId, { page, limit });
      const sessionMessages = response.data;

      if (page === 1) {
        messages.value[sessionId] = sessionMessages;
      } else {
        // 分页加载，插入到开头
        messages.value[sessionId] = [
          ...sessionMessages,
          ...(messages.value[sessionId] || []),
        ];
      }

      return response;
    } catch (error) {
      throw error;
    }
  };

  const sendMessage = async (content: string, type: MessageType = "text") => {
    if (!currentSessionId.value || !canSendMessage.value) {
      throw new Error("无法发送消息");
    }

    try {
      isLoading.value = true;

      // 创建临时消息
      const tempMessage: ChatMessage = {
        id: `temp-${Date.now()}`,
        sessionId: currentSessionId.value,
        content,
        type,
        role: "user",
        attachments: [...attachments.value],
        createdAt: new Date(),
        updatedAt: new Date(),
        status: "sending",
      };

      // 添加到消息列表
      if (!messages.value[currentSessionId.value]) {
        messages.value[currentSessionId.value] = [];
      }
      messages.value[currentSessionId.value].push(tempMessage);

      // 发送消息
      const response = await chatApi.sendMessage({
        sessionId: currentSessionId.value,
        content,
        type,
        attachments: attachments.value.map((att) => att.id),
      });

      // 更新消息状态
      const messageIndex = messages.value[currentSessionId.value].findIndex(
        (m) => m.id === tempMessage.id,
      );
      if (messageIndex !== -1) {
        messages.value[currentSessionId.value][messageIndex] = response.data;
      }

      // 清空附件
      attachments.value = [];

      return response;
    } catch (error) {
      // 更新消息状态为失败
      if (currentSessionId.value && messages.value[currentSessionId.value]) {
        const messageIndex = messages.value[currentSessionId.value].findIndex(
          (m) => m.id?.startsWith("temp-"),
        );
        if (messageIndex !== -1) {
          messages.value[currentSessionId.value][messageIndex].status =
            "failed";
        }
      }
      throw error;
    } finally {
      isLoading.value = false;
    }
  };

  const sendStreamMessage = async (
    content: string,
    type: "text" | "image" | "file" = "text",
  ) => {
    try {
      if (!currentSession.value) {
        await createSession();
      }

      if (!websocket || websocket.readyState !== WebSocket.OPEN) {
        throw new Error("WebSocket连接未建立");
      }

      // 添加用户消息
      const userMessage: ChatMessage = {
        id: `temp-${Date.now()}`,
        sessionId: currentSession.value.id,
        content,
        type,
        role: "user",
        timestamp: new Date(),
        status: "sent",
      };

      messages.value.push(userMessage);

      // 创建流式回复消息
      streamingMessage.value = {
        id: `stream-${Date.now()}`,
        sessionId: currentSession.value.id,
        content: "",
        type: "text",
        role: "assistant",
        timestamp: new Date(),
        status: "streaming",
      };

      messages.value.push(streamingMessage.value);
      setTyping(true);

      // 发送WebSocket消息
      websocket.send(
        JSON.stringify({
          type: "chat",
          data: {
            sessionId: currentSession.value.id,
            content,
            messageType: type,
            personaId: currentPersona.value?.id,
          },
        }),
      );
    } catch (error) {
      setTyping(false);
      throw error;
    }
  };

  const deleteMessage = async (messageId: string) => {
    await chatApi.deleteMessage(messageId);

    // 从所有会话的消息中移除
    Object.keys(messages.value).forEach((sessionId) => {
      const messageIndex = messages.value[sessionId].findIndex(
        (m) => m.id === messageId,
      );
      if (messageIndex !== -1) {
        messages.value[sessionId].splice(messageIndex, 1);
      }
    });
  };

  const editMessage = async (messageId: string, content: string) => {
    const response = await chatApi.editMessage(messageId, { content });
    const updatedMessage = response.data;

    // 更新本地消息
    Object.keys(messages.value).forEach((sessionId) => {
      const messageIndex = messages.value[sessionId].findIndex(
        (m) => m.id === messageId,
      );
      if (messageIndex !== -1) {
        messages.value[sessionId][messageIndex] = updatedMessage;
      }
    });

    return response;
  };

  const regenerateMessage = async (messageId: string) => {
    const response = await chatApi.regenerateMessage(messageId);
    const newMessage = response.data;

    // 替换原消息
    Object.keys(messages.value).forEach((sessionId) => {
      const messageIndex = messages.value[sessionId].findIndex(
        (m) => m.id === messageId,
      );
      if (messageIndex !== -1) {
        messages.value[sessionId][messageIndex] = newMessage;
      }
    });

    return response;
  };

  const markAsRead = async (sessionId: string) => {
    await chatApi.markAsRead(sessionId);

    // 更新未读计数
    unreadCounts.value[sessionId] = 0;

    // 更新会话的最后阅读时间
    const session = sessions.value.find((s) => s.id === sessionId);
    if (session) {
      session.lastReadAt = new Date().toISOString();
    }
  };

  const updateSession = async (
    sessionId: string,
    updates: { title?: string; archived?: boolean },
  ) => {
    const response = await chatApi.updateSession(sessionId, updates);
    const updatedSession = response.data;

    // 更新本地会话
    const index = sessions.value.findIndex((s) => s.id === sessionId);
    if (index !== -1) {
      sessions.value[index] = updatedSession;
    }

    return response;
  };

  const deleteSession = async (sessionId: string) => {
    await chatApi.deleteSession(sessionId);

    // 从本地移除
    const index = sessions.value.findIndex((s) => s.id === sessionId);
    if (index !== -1) {
      sessions.value.splice(index, 1);
    }

    // 清理相关数据
    delete messages.value[sessionId];
    delete unreadCounts.value[sessionId];

    // 如果删除的是当前会话，清空当前会话ID
    if (currentSessionId.value === sessionId) {
      currentSessionId.value = null;
    }
  };

  const archiveSession = async (sessionId: string) => {
    return updateSession(sessionId, { archived: true });
  };

  const unarchiveSession = async (sessionId: string) => {
    return updateSession(sessionId, { archived: false });
  };

  const clearHistory = async (sessionId: string) => {
    await chatApi.clearHistory(sessionId);

    // 清空本地消息
    messages.value[sessionId] = [];

    // 重置未读计数
    unreadCounts.value[sessionId] = 0;
  };

  const exportSession = async (
    sessionId: string,
    format: "json" | "txt" | "md" = "json",
  ) => {
    const response = await chatApi.exportSession(sessionId, format);
    return response.data;
  };

  const searchMessages = async (sessionId: string, query: string) => {
    const response = await chatApi.searchMessages(sessionId, { query });
    return response.data;
  };

  const addAttachment = (file: File) => {
    const attachment = {
      id: Date.now().toString(),
      file,
      name: file.name,
      size: file.size,
      type: file.type,
      url: URL.createObjectURL(file),
    };
    attachments.value.push(attachment);
    return attachment;
  };

  const removeAttachment = (attachmentId: string) => {
    const index = attachments.value.findIndex((a) => a.id === attachmentId);
    if (index !== -1) {
      const attachment = attachments.value[index];
      // 释放对象URL
      if (attachment.url) {
        URL.revokeObjectURL(attachment.url);
      }
      attachments.value.splice(index, 1);
    }
  };

  const clearAttachments = () => {
    // 释放所有对象URL
    attachments.value.forEach((attachment) => {
      if (attachment.url) {
        URL.revokeObjectURL(attachment.url);
      }
    });
    attachments.value = [];
  };

  const setStreamingMessage = (messageId: string | null) => {
    streamingMessageId.value = messageId;
  };

  const getSessionStats = async (sessionId: string) => {
    const response = await chatApi.getSessionStats(sessionId);
    return response.data;
  };

  const getUserChatStats = async () => {
    const response = await chatApi.getUserChatStats();
    return response.data;
  };

  const switchPersona = async (personaId: string) => {
    const persona = personas.value.find((p) => p.id === personaId);
    if (!persona) throw new Error("人格不存在");

    currentPersona.value = persona;

    // 如果有当前会话，更新会话的人格
    if (currentSession.value) {
      await chatApi.updateSession(currentSession.value.id, { personaId });
      currentSession.value.personaId = personaId;
    }
  };

  const markSessionAsRead = async (sessionId: string) => {
    await chatApi.markAsRead(sessionId);

    const session = sessions.value.find((s) => s.id === sessionId);
    if (session) {
      session.unreadCount = 0;
    }
  };

  const connectWebSocket = async () => {
    const wsUrl = `${import.meta.env.VITE_WS_BASE_URL || "ws://localhost:8080"}/ws/chat`;
    websocket = new WebSocket(wsUrl);

    websocket.onopen = () => {
      isConnected.value = true;

      // 开始心跳
      startHeartbeat();
    };

    websocket.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        handleWebSocketMessage(data);
      } catch (error) {
        // 忽略WebSocket消息处理错误
      }
    };

    websocket.onclose = () => {
      isConnected.value = false;
      setTyping(false);
      // WebSocket连接已关闭

      // 尝试重连
      scheduleReconnect();
    };

    websocket.onerror = () => {
      isConnected.value = false;
    };
  };

  const handleWebSocketMessage = (data: any) => {
    switch (data.type) {
      case "message_chunk":
        if (streamingMessage.value) {
          streamingMessage.value.content += data.content;
        }
        break;

      case "message_complete":
        if (streamingMessage.value) {
          streamingMessage.value.status = "sent";
          streamingMessage.value.id = data.messageId;
          streamingMessage.value = null;
        }
        setTyping(false);
        break;

      case "typing":
        setTyping(data.isTyping);
        break;

      case "error":
        if (streamingMessage.value) {
          streamingMessage.value.status = "failed";
          streamingMessage.value = null;
        }
        setTyping(false);
        break;

      case "pong":
        // 心跳响应
        break;

      default:
      // 未知WebSocket消息类型
    }
  };

  const startHeartbeat = () => {
    heartbeatTimer = setInterval(() => {
      if (websocket && websocket.readyState === WebSocket.OPEN) {
        websocket.send(JSON.stringify({ type: "ping" }));
      }
    }, 30000); // 30秒心跳
  };

  const scheduleReconnect = () => {
    if (reconnectTimer) return;

    reconnectTimer = setTimeout(() => {
      connectWebSocket();
      reconnectTimer = null;
    }, 5000); // 5秒后重连
  };

  const setLoading = (loading: boolean) => {
    isLoading.value = loading;
  };

  const setTyping = (typing: boolean) => {
    isTyping.value = typing;
  };

  const cleanup = () => {
    if (websocket) {
      websocket.close();
      websocket = null;
    }

    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }

    if (heartbeatTimer) {
      clearInterval(heartbeatTimer);
      heartbeatTimer = null;
    }

    isConnected.value = false;
    setTyping(false);
  };

  return {
    // 状态
    sessions,
    currentSessionId,
    messages,
    isLoading,
    isStreaming,
    streamingMessageId,
    currentPersona,
    attachments,
    unreadCounts,

    // 计算属性
    currentSession,
    currentMessages,
    activeSessions,
    archivedSessions,
    totalUnreadCount,
    hasAttachments,
    canSendMessage,
    filteredSessions,
    availablePersonas,
    currentPersonaName,

    // 动作
    initChat,
    fetchPersonas,
    fetchSessions,
    loadUnreadCounts,
    createSession,
    selectSession,
    loadMessages,
    sendMessage,
    sendStreamMessage,
    deleteMessage,
    editMessage,
    regenerateMessage,
    markAsRead,
    updateSession,
    deleteSession,
    archiveSession,
    unarchiveSession,
    clearHistory,
    exportSession,
    searchMessages,
    addAttachment,
    removeAttachment,
    clearAttachments,
    setStreamingMessage,
    getSessionStats,
    getUserChatStats,
    switchPersona,
    markSessionAsRead,
    connectWebSocket,
    setLoading,
    setTyping,
    cleanup,
  };
});
